/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package window;

import java.util.*;
import java.util.concurrent.Callable;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
//import java.util.concurrent.

/**
 *
 * @author Arcanis
 */
public class SearchPanel extends javax.swing.JPanel {

    private boolean criteriaChanged = false;
    private List<EmailMessage> messages = new ArrayList<EmailMessage>();
    private List<EmailMessage> found = new ArrayList<EmailMessage>();
    private ArrayList<ArrayList<EmailPart>> foundWhereList = new ArrayList<ArrayList<EmailPart>>();
    private String keptPatern;
    
    
    public class EmailMessage {
        public String from;
        public String subject;
        public String body;
        public String received;
        
        public EmailMessage(String from, String subject, String body, String received) {
            this.from = from;
            this.subject = subject;
            this.body = body;
            this.received = received;
        }
    }
    
    
    
    
    
    private void initFakeData() {
        this.messages.add(new EmailMessage("pavel.janecka@gmail.com", "pozdrav z hor", "je tu kosa", "12.5.2012 14:54"));
        this.messages.add(new EmailMessage("pavel.janecka@gmail.com", "pozdrav od jineho more", "je tu horko", "11.5.2012 14:54"));
        this.messages.add(new EmailMessage("pavel.janecka@gmail.com", "pozdrav z piscite sahary", "je tu jiny pisek", "12.2.2012 14:54"));
        this.messages.add(new EmailMessage("nekdo.jiny@gmail.com", "nikoho nezdravim", "pisu jen tak", "12.5.2012 14:54"));
        this.messages.add(new EmailMessage("nekdo.jiny@gmail.com", "nevidel jsem nikoho", "random text proste", "12.5.2012 14:54"));
        this.messages.add(new EmailMessage("nekdo.jiny@gmail.com", "ad random text", "proc bych nekomu posilal random text?", "12.5.2012 14:54"));
        
        drpSortBy.add("from", new JLabel("from"));
        drpSortBy.add("subject", new JLabel("subject"));
        drpSortBy.add("received", new JLabel("received"));
        this.keptPatern = "";
    }
    
    
    /**
     * Creates new form SearchPanel
     */
    public SearchPanel() {
        initComponents();
        initFakeData();
    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jLabel1 = new javax.swing.JLabel();
        pnlSearchResults = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtResultArea = new javax.swing.JTextArea();
        lblSearch = new javax.swing.JLabel();
        chkSender = new javax.swing.JCheckBox();
        chkSubject = new javax.swing.JCheckBox();
        chkMessageBody = new javax.swing.JCheckBox();
        txtSearch = new javax.swing.JTextField();
        lblResult = new javax.swing.JLabel();
        radTyped = new javax.swing.JRadioButton();
        drpSortBy = new javax.swing.JComboBox();

        jLabel1.setText("jLabel1");

        pnlSearchResults.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(80, 80, 80), 1, true), "Search"));

        txtResultArea.setColumns(20);
        txtResultArea.setRows(5);
        jScrollPane1.setViewportView(txtResultArea);

        javax.swing.GroupLayout pnlSearchResultsLayout = new javax.swing.GroupLayout(pnlSearchResults);
        pnlSearchResults.setLayout(pnlSearchResultsLayout);
        pnlSearchResultsLayout.setHorizontalGroup(
            pnlSearchResultsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlSearchResultsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1))
        );
        pnlSearchResultsLayout.setVerticalGroup(
            pnlSearchResultsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
        );

        lblSearch.setText("Search:");

        chkSender.setSelected(true);
        chkSender.setText("sender");
        chkSender.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkSenderActionPerformed(evt);
            }
        });

        chkSubject.setText("subject");
        chkSubject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkSubjectActionPerformed(evt);
            }
        });

        chkMessageBody.setText("message body");
        chkMessageBody.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkMessageBodyActionPerformed(evt);
            }
        });

        txtSearch.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtSearchKeyReleased(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                txtSearchKeyTyped(evt);
            }
        });

        lblResult.setText("result");

        radTyped.setEnabled(false);
        radTyped.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                radTypedActionPerformed(evt);
            }
        });

        drpSortBy.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        drpSortBy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                drpSortByActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlSearchResults, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(chkSender)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(chkSubject)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(chkMessageBody)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(drpSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 4, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(lblSearch)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 129, Short.MAX_VALUE)
                        .addComponent(radTyped)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(lblResult)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(chkSender)
                    .addComponent(chkSubject)
                    .addComponent(chkMessageBody)
                    .addComponent(drpSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblSearch)
                    .addComponent(txtSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblResult)
                    .addComponent(radTyped))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(pnlSearchResults, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void txtSearchKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtSearchKeyTyped
        criteriaChanged = true;        
    }//GEN-LAST:event_txtSearchKeyTyped

    enum EmailPart {
        BODY,
        FROM,
        SUBJECT
    }
      
    private class CompletionTask implements Runnable {
        EmailMessage msg;
        String pattern;
        ArrayList<EmailPart> foundWhere;
        
        CompletionTask(EmailMessage msg, String pattern, ArrayList<EmailPart> foundWhere) {
            this.msg = msg;
            this.pattern = pattern;
            this.foundWhere = foundWhere;
        }
        
        public void run() {
            //pnlSearchResults.add(new JLabel("from: " + this.msg.from + "; subject: " + this.msg.subject));
            if (!foundWhere.isEmpty())
            txtResultArea.insert("\nfrom: " + this.msg.from + "; subject: " + this.msg.subject+"; date: " + this.msg.received, 0);            
        }
    }
    
    private void txtSearchKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtSearchKeyReleased
        if (criteriaChanged) {
            // Perform action only if the search criteria changed
            lblResult.setText(txtSearch.getText());
            criteriaChanged = false;
            
            txtResultArea.setText("");
            
            String pattern = lblResult.getText();
            ArrayList<EmailMessage> matches = new ArrayList<>();
            ArrayList<EmailPart> foundWhere = new ArrayList<EmailPart>();
            ArrayList<ArrayList<EmailPart>> tmpFoundWhereList = new ArrayList<ArrayList<EmailPart>>();
            if (!pattern.isEmpty()) {
                for (int i = 0; i < messages.size(); i++) {
                    EmailMessage msg = messages.get(i);
                    if(chkSender.isSelected() && msg.from.contains(pattern)) {
                        foundWhere.add(EmailPart.FROM);                        
                    }
                    if (chkSubject.isSelected() && msg.subject.contains(pattern)) {
                        foundWhere.add(EmailPart.SUBJECT);
                    }

                    if (!foundWhere.isEmpty()) {
                        ArrayList<EmailPart> cpy = (ArrayList<EmailPart>) foundWhere.clone();
                        SwingUtilities.invokeLater(new CompletionTask(msg, pattern, cpy));
                        foundWhere.clear();
                        matches.add(msg);
                        tmpFoundWhereList.add(cpy);
                    }
                }
            }
            this.foundWhereList = tmpFoundWhereList;
            this.found = matches;
            this.keptPatern = pattern;
        }              
    }//GEN-LAST:event_txtSearchKeyReleased

    private void radTypedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_radTypedActionPerformed
        //this.criteriaChanged = true;
    }//GEN-LAST:event_radTypedActionPerformed

    private void chkSenderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkSenderActionPerformed
        this.criteriaChanged = true;
        txtSearchKeyReleased(null);
    }//GEN-LAST:event_chkSenderActionPerformed

    private void chkSubjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkSubjectActionPerformed
        this.criteriaChanged = true;
        txtSearchKeyReleased(null);
    }//GEN-LAST:event_chkSubjectActionPerformed

    private void chkMessageBodyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkMessageBodyActionPerformed
        
    }//GEN-LAST:event_chkMessageBodyActionPerformed

    private void drpSortByActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_drpSortByActionPerformed
        //if (((JComboBox) evt.getSource()).)
        for (int i = 0; i < this.found.size(); i++) {
            SwingUtilities.invokeLater(new CompletionTask(this.found.get(i), this.keptPatern, this.foundWhereList.get(i)));
                
        }
    }//GEN-LAST:event_drpSortByActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox chkMessageBody;
    private javax.swing.JCheckBox chkSender;
    private javax.swing.JCheckBox chkSubject;
    private javax.swing.JComboBox drpSortBy;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblResult;
    private javax.swing.JLabel lblSearch;
    private javax.swing.JPanel pnlSearchResults;
    private javax.swing.JRadioButton radTyped;
    private javax.swing.JTextArea txtResultArea;
    private javax.swing.JTextField txtSearch;
    // End of variables declaration//GEN-END:variables
}
